iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0
Modern Web

React 學得動嗎系列 第 16

[Day 16] React 進階技巧:HOC 與 Render Props

  • 分享至 

  • xImage
  •  

今天,我們將學習 React 中兩個重要的程式碼重用技巧:高階元件(HOC)和渲染屬性(Render Props)。這些技巧是提升程式碼可讀性與重用性的工具,能顯著提升專案開發的效率。

高階組件 (HOC):React 的彈性擴展技術

高階組件(Higher-Order Component, HOC),是一種設計模式,它允許我們將共用的邏輯提取出來並應用到多個元件上。HOC 透過將元件作為參數,返回一個新的強化版元件,從而實現邏輯的重用。

HOC 是什麼?

簡單來說,HOC 是一個接受元件並返回新元件的函數。我們來看一個具體的範例:

function withSuperpowers(WrappedComponent) {
  return class extends React.Component {
    render() {
      return (
        <div className="superpowers">
          <WrappedComponent {...this.props} extraPower="飛行能力" />
        </div>
      );
    }
  }
}

// 使用 HOC
const SuperHero = withSuperpowers(NormalHero);

在這個例子中,withSuperpowers 是一個 HOC,它將 NormalHero 元件包裝成一個具備額外功能的新元件。

HOC 的實際應用

HOC 通常應用於以下場景:

  1. 權限控制:檢查用戶是否有權限查看某個元件。
  2. 數據獲取:為元件注入通用的資料獲取邏輯。
  3. 狀態管理:為無狀態元件增加狀態管理功能。

以下是一個 HOC 的實際應用範例:

function withDataFetching(WrappedComponent, dataSource) {
  return class extends React.Component {
    state = {
      data: null,
      isLoading: true,
      error: null
    };

    componentDidMount() {
      fetch(dataSource)
        .then(response => response.json())
        .then(data => this.setState({ data, isLoading: false }))
        .catch(error => this.setState({ error, isLoading: false }));
    }

    render() {
      const { data, isLoading, error } = this.state;
      return (
        <WrappedComponent 
          data={data} 
          isLoading={isLoading} 
          error={error} 
          {...this.props} 
        />
      );
    }
  }
}

// 使用 HOC
const UserListWithData = withDataFetching(UserList, 'https://api.example.com/users');

這個範例中,HOC 為元件增加了資料獲取的能力,提升了程式碼的可重用性。

渲染屬性 (Render Props):React 的靈活渲染技術

渲染屬性(Render Props)是一種在 React 元件之間共享程式碼的模式。它透過將函數作為 props 傳遞,允許元件根據需要自定義渲染的內容。

Render Props 是什麼?

Render Props 是指一個 props 的值為函數,該函數用於決定元件應如何渲染內容。這樣的設計模式為元件之間的行為和狀態共享提供了極大的靈活性。

以下是一個範例:

class Mouse extends React.Component {
  state = { x: 0, y: 0 };

  handleMouseMove = (event) => {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }

  render() {
    return (
      <div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
        {this.props.render(this.state)}
      </div>
    );
  }
}

// 使用 Render Props
<Mouse render={({ x, y }) => (
  <h1>鼠標的位置是 ({x}, {y})</h1>
)}/>

在這個範例中,Mouse 元件透過 render 函數動態渲染內容,這樣的設計讓渲染邏輯更加靈活。

Render Props 的實際應用

Render Props 模式適合以下場景:

  1. 狀態共享:多個元件需要共享相同的狀態或行為。
  2. 條件渲染:根據不同的條件渲染內容。
  3. 元件組合:將多個元件組合在一起以構建更複雜的介面。

以下是使用 Render Props 的資料獲取範例:

class DataFetcher extends React.Component {
  state = {
    data: null,
    isLoading: true,
    error: null
  };

  componentDidMount() {
    fetch(this.props.url)
      .then(response => response.json())
      .then(data => this.setState({ data, isLoading: false }))
      .catch(error => this.setState({ error, isLoading: false }));
  }

  render() {
    return this.props.children(this.state);
  }
}

// 使用 Render Props
<DataFetcher url="https://api.example.com/users">
  {({ data, isLoading, error }) => {
    if (isLoading) return <div>載入中...</div>;
    if (error) return <div>哎呀,出錯了!</div>;
    return <UserList users={data} />;
  }}
</DataFetcher>

這個範例展示了如何利用 Render Props 模式來分離資料獲取邏輯和 UI 渲染邏輯。

小結

今天,我們學習了 React 中兩種重要的進階技術:高階元件(HOC)和渲染屬性(Render Props)。這兩種技術都能幫助開發者在元件之間重用邏輯,提升程式碼的可維護性與靈活性。

高階元件適用於為元件提供通用功能,而渲染屬性則可以靈活地決定元件的渲染方式。在實際開發中,可以根據具體需求選擇適合的技術,甚至將它們結合使用,達到最佳的開發效果。

如果你想更深入地了解這些技巧,可以查看 React 官方文件中關於高階組件的部分渲染屬性的部分


上一篇
[Day 15] React如何規劃專案結構
下一篇
[Day 17] 幾個React 效能優化技巧
系列文
React 學得動嗎30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言